package redislock

import (
	"sync"
	"sync/atomic"
)

// LocalLock 本地任务的锁
type LocalLock struct {
	quoteCnt atomic.Int64 // 引用次数，当引用次数为0时会释放
	c        chan bool    // 通道，用于实现锁
}

// localLockMap 存放锁的map
var localLockMap = make(map[string]*LocalLock)

// handleLocalLockMapMx 操作localLockMap的锁
var handleLocalLockMapMx sync.Mutex

// getCacheKeyInfo 获取localLockMap的大小
func getCacheKeyInfo(key string) *LocalLock {
	handleLocalLockMapMx.Lock()
	defer handleLocalLockMapMx.Unlock()
	return localLockMap[key]
}

// getLocalLock 获取本地锁
func getLocalLock(key string) *LocalLock {
	handleLocalLockMapMx.Lock()
	defer handleLocalLockMapMx.Unlock()

	mutexItem, isOk := localLockMap[key]
	if isOk {
		mutexItem.quoteCnt.Add(1)
		return mutexItem
	}
	mutexItem = &LocalLock{c: make(chan bool, 1)}
	mutexItem.quoteCnt.Store(1)
	mutexItem.c <- true // 默认未持有锁

	localLockMap[key] = mutexItem
	return mutexItem
}

// releaseLocalLock 释放本地锁
func releaseLocalLock(key string) {
	handleLocalLockMapMx.Lock()
	defer handleLocalLockMapMx.Unlock()

	mutexItem, isOk := localLockMap[key]
	if !isOk {
		return
	}
	mutexItem.quoteCnt.Add(-1)
	if mutexItem.quoteCnt.Load() <= 0 {
		//fmt.Println("释放本地锁", key)
		delete(localLockMap, key)
		return
	}
	mutexItem.c <- true
}
